<template>
  <demo-content :title="title">
    <p>
      该例子创建了一条路径，它由两个圆形所组成，其中一个圆形在另一个的内部。通过设定
      arc() 方法的最后一个参数，该应用程序以顺时针方向绘制了内部的圆形，并且
      以逆时针方向绘制了外围的圆形。
    </p>
    <p>
      在创建好路径后，应用程序对该路径进行填充。浏览器运用“非零环绕规则”，对外围圆形的内部进行了填充。
      不过填充的范围不包括里面的圆，这就产生了一种剪纸图案的效果。
    </p>
    <p>
      计数规则：如果与路径的顺时针部分相交，则加1，如果与路径的逆时针部分相交，则减1。
    </p>
    <p>
      <strong>
        在下图的两个圆之间有一条横线，根据 Canvas 规范，当使用 arc
        向当前路径中增加子路径时，该方法必须将一条子路径的终点与所画圆弧的起点相连。
      </strong>
    </p>
    <div style="position: relative">
      <label style="position: absolute; left: 460px; top: 15px">
        <input v-model="sameDirection" type="checkbox" />
        <span>Same direction</span>
      </label>
      <label style="position: absolute; left: 460px; top: 40px">
        <input v-model="annotations" type="checkbox" />
        <span>Annotations</span>
      </label>
      <canvas ref="canvasRef" width="600" height="450"></canvas>
    </div>
  </demo-content>
</template>

<script setup lang="ts">
import { onMounted, ref, watch } from "vue";
import { drawGrid, rect, text } from "./utils";

const title = "剪纸效果";
// 指定组件上的属性
defineOptions({ title });

const canvasRef = ref<HTMLCanvasElement>();
const sameDirection = ref(false);
const annotations = ref(true);

watch(annotations, updateCanvas);
watch(sameDirection, updateCanvas);
let ctx: CanvasRenderingContext2D;

function updateCanvas() {
  rect.clear(ctx, { x: 0, y: 0, w: ctx.canvas.width, h: ctx.canvas.height });
  drawGrid(ctx, { stepx: 15, stepy: 15 });
  text.draw(ctx, {
    text: "Two arcs, one path",
    x: 10,
    y: 30,
    fontSize: 18,
    fillStyle: "#0000c1",
  });
  if (annotations.value) {
    text.draw(ctx, {
      text: sameDirection.value ? "CW" : "CCW",
      x: 420,
      y: 100,
      fontSize: 20,
      fillStyle: "blue",
    });
    text.draw(ctx, {
      text: "CW",
      x: 340,
      y: 180,
      fontSize: 20,
      fillStyle: "blue",
    });
    ctx.beginPath();
    ctx.strokeStyle = "blue";
    text.draw(ctx, {
      text: "+1",
      x: 220,
      y: 200,
      fontSize: 18,
    });
    text.draw(ctx, {
      text: sameDirection.value ? "+1" : "-1",
      x: 120,
      y: 230,
      fontSize: 18,
    });
    text.draw(ctx, {
      text: sameDirection.value ? "+1" : "-1",
      x: 440,
      y: 270,
      fontSize: 18,
    });
    ctx.beginPath();
    ctx.moveTo(300, 200);
    ctx.lineTo(100, 250);
    ctx.moveTo(410, 260);
    ctx.lineTo(500, 300);
    ctx.stroke();
  }
  text.draw(ctx, {
    text: "ctx.arc(300, 200, 150, 0, Math.PI * 2, sameDirection.value)",
    x: 20,
    y: 400,
    fontSize: 16,
    fillStyle: "#0011ff",
  });
  text.draw(ctx, {
    text: "ctx.arc(300, 200, 100, 0, Math.PI * 2, true);",
    x: 20,
    y: 425,
    fontSize: 16,
    fillStyle: "#0011ff",
  });
  ctx.save();
  // ctx.strokeStyle = "red";
  ctx.fillStyle = "rgba(100,140,230,0.5)";
  ctx.shadowColor = "rgba(0,0,0,0.8)";
  ctx.shadowOffsetX = 10;
  ctx.shadowOffsetY = 10;
  ctx.shadowBlur = 10;
  ctx.beginPath();
  ctx.arc(300, 200, 150, 0, Math.PI * 2, sameDirection.value);
  ctx.arc(300, 200, 100, 0, Math.PI * 2, true);
  ctx.fill();
  ctx.stroke();
  ctx.restore();
}

onMounted(() => {
  const canvas = canvasRef.value!;
  ctx = canvas.getContext("2d")!;
  updateCanvas();
});
</script>

<style src="./default.css" scoped></style>
